package com.seari.main.line17;

import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import com.google.common.collect.Iterables;
import com.seari.bean.iec104.AiData;
import com.seari.bean.iec104.DataTransferBean;
import com.seari.bean.iec104.DiData;
import com.seari.pojo.QueryDataTransferBean;
import com.seari.service.AiDataService;
import com.seari.service.DataTransferService;
import com.seari.service.DiDataService;
import com.seari.utils.JedisPoolUtils;
import com.seari.utils.MiscTools;
import org.springframework.util.CollectionUtils;

import redis.clients.jedis.Jedis;

@Component
@Order(value = 3)
public class Line17NewStarter implements ApplicationRunner
{
	final static Logger logger = LoggerFactory.getLogger(Line17NewStarter.class);
	public static final int MAX_WORKER_COUNT = 10;
	public static final int MAX_SLICE_COUNT = 2000;
	public static int STARTER_SLEEP_SECONDS = 30;
	public static BlockingQueue<List<String>> aiQueue = new LinkedBlockingQueue<>(2000);
	public static BlockingQueue<List<String>> diQueue = new LinkedBlockingQueue<>(2000);
	public static ExecutorService service = Executors.newCachedThreadPool();
	public static AtomicInteger workerCount = new AtomicInteger();
	public static Map<String,AiData> aiDataMap = new HashMap<>();
	public static Map<String,DiData> diDataMap = new HashMap<>();
	//MASTER模式用于朱家角数据转发（为兼容老接口），SLAVE模式用于杂散电流与可视化接地数据转发（新接口）
	public static String work_mode = "MASTER";
	public static String configFilePath = "config.cfg";
        private static Map<String,List<DataTransferBean>> workGroup = new HashMap<>(); 
	public static Properties config;
	static Jedis jedis = JedisPoolUtils.getJedis();
	
	@Autowired
	private AiDataService aiDataService;
	
	@Autowired
	private DiDataService diDataService;
        
        @Autowired
        private DataTransferService dataTransferService;
	
	@Override
	public void run(ApplicationArguments args) throws Exception
	{
		// TODO Auto-generated method stub
		initConfigData();
		logger.info("init complete");
		if(work_mode.equals("MASTER"))
		{
			//MASTER模式转发代码（老接口，期安综合监控）
			getMasterConfig();
			while (true)
			{
				Set<String> aiKeyset = jedis.hkeys("line17_AI");
				Iterable<List<String>> aiSets = Iterables.partition(aiKeyset,MAX_SLICE_COUNT);
				Iterator<List<String>> aiIterator = aiSets.iterator();
				while (aiIterator.hasNext())
				{
					List<String> list = aiIterator.next();
					aiQueue.add(list);
				}
				
				Set<String> diKeyset = jedis.hkeys("line17_DI");
				Iterable<List<String>> diSets = Iterables.partition(diKeyset,MAX_SLICE_COUNT);
				Iterator<List<String>> diIterator = diSets.iterator();
				while (diIterator.hasNext())
				{
					List<String> list = diIterator.next();
					diQueue.add(list);
				}
				startMasterWorker();
				logger.info("start worker>>>>>>");
				TimeUnit.SECONDS.sleep(STARTER_SLEEP_SECONDS);
			}
		}else if (work_mode.equals("SLAVE")) {
			//SLAVE模式转发代码（新接口，可视化接地、杂散电流）
			getSlaveConfig();
            for (Map.Entry<String, List<DataTransferBean>> entry : workGroup.entrySet()) 
            {
                Iterable<List<DataTransferBean>> job = Iterables.partition(entry.getValue(), MAX_SLICE_COUNT);
                Iterator<List<DataTransferBean>> jobIterator = job.iterator();
                while (jobIterator.hasNext())
                {
					Line17SlaveWorker worker = new Line17SlaveWorker();
					worker.setGroup(entry.getKey());
					worker.setGap(Integer.parseInt(config.getProperty("SLAVE_" + entry.getKey().toUpperCase() + "_GAP", "30"))); //默认间隔30秒
					worker.setJobList(jobIterator.next());
					new Thread(worker).start();
                }
            }
		}else {
			//系统退出
			System.exit(0);
		}
	}
	
	public void startMasterWorker()
	{
		while(workerCount.get() < MAX_WORKER_COUNT)
		{
			Line17MasterWorker worker = new Line17MasterWorker(aiQueue, diQueue);
			service.submit(worker);
			int num = workerCount.incrementAndGet();
			logger.info("start worker:current work count is:" + num);
		}
		System.out.println("worker thread start complete!");
	}
	
	private void initConfigData()
	{
		try
		{
			config = MiscTools.loadConfig(configFilePath);			
			work_mode = config.getProperty("WORK_MODE","MASTER");//默认使用MASTER模式
		} catch (Exception e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	//MASTER模式下的数据配置
	private void getMasterConfig()
	{
		//RABBITMQ配置
		List<AiData> aiDatas = aiDataService.getAiDataInfo();
		List<DiData> diDatas = diDataService.getDiDataInfo();
		Line17MasterWorker.MQ_HOST = config.getProperty("MQ_HOST");
		Line17MasterWorker.MQ_PORT = Integer.parseInt(config.getProperty("MQ_PORT"));
		Line17MasterWorker.MQ_VIRTUALHOST = config.getProperty("MQ_VIRTUALHOST");
		Line17MasterWorker.MQ_USER = config.getProperty("MQ_USER");
		Line17MasterWorker.MQ_PASS = config.getProperty("MQ_PASS");
		Line17MasterWorker.MQ_EXCHANGE = config.getProperty("MQ_EXCHANGE");
		Line17MasterWorker.MQ_ROUTINGKEY = config.getProperty("MQ_ROUTINGKEY");
		//线程休眠配置
		STARTER_SLEEP_SECONDS = Integer.parseInt(config.getProperty("STARTER_SLEEP_SECONDS", "30"));//默认休眠30秒
		for (AiData aiData : aiDatas)
		{
			aiDataMap.put(aiData.getPoint()+"", aiData);
		}
		
		for (DiData diData : diDatas)
		{
			diDataMap.put(diData.getPoint()+"", diData);
		}
	}
	
	//SLAVE模式下的数据配置
	private void getSlaveConfig()
	{
            //RABBITMQ配置
            Line17SlaveWorker.MQ_HOST = config.getProperty("MQ_HOST");
            Line17SlaveWorker.MQ_PORT = Integer.parseInt(config.getProperty("MQ_PORT"));
            Line17SlaveWorker.MQ_VIRTUALHOST = config.getProperty("MQ_VIRTUALHOST");
            Line17SlaveWorker.MQ_USER = config.getProperty("MQ_USER");
            Line17SlaveWorker.MQ_PASS = config.getProperty("MQ_PASS");
            Line17SlaveWorker.MQ_EXCHANGE = config.getProperty("MQ_EXCHANGE");
            Line17SlaveWorker.MQ_ROUTINGKEY = config.getProperty("MQ_ROUTINGKEY");
            //点表分组配置
            String[] groupsStrs = config.getProperty("SLAVE_GROUP").split("\\|");
            for (String groupsStr : groupsStrs) 
            {
                QueryDataTransferBean queryDataTransferBean = new QueryDataTransferBean();
                queryDataTransferBean.setGroup(groupsStr);
                List<DataTransferBean> dataTransferBeans = dataTransferService.getDataTransfer(queryDataTransferBean);
                if(!CollectionUtils.isEmpty(dataTransferBeans))
                {
                    workGroup.put(groupsStr, dataTransferBeans);
                }
            }
	}

}
